<?php
declare (strict_types = 1);

namespace app\frontend\controller;

use app\frontend\model\UserProject;
use think\facade\Db;
use think\facade\Validate;

class Plan extends Base
{
    // 计划列表页
    public function index()
    {
        // 找出当前用户所属的所有项目
        $userInfo = session('userInfo');
        $projectIds = UserProject::field('id,project_id')
            ->where('user_id', $userInfo['id'])
            ->column('project_id');
        $projects = \app\frontend\model\Project::field('id,name')->select($projectIds)->toArray();

        return view('', [
            'projects' => $projects
        ]);
    }

    // 计划列表数据接口
    public function list()
    {
        $page = request()->param('page');
        $limit = request()->param('limit');
        $project = request()->param('project');
        $status = request()->param('status');
        $name = request()->param('name');
        $requirement = request()->param('requirement');

        if ($status == 'all') {
            $status = [1, 2, 3];
        } else {
            $status = [$status];
        }

        $userInfo = session('userInfo');
        $query = \app\frontend\model\Plan::with(['project'])
            ->field('id,project_id,name,start_time,end_time,status,priority')
            ->where('user_id', $userInfo['id']);
        if (!empty($requirement)) {
            $query = $query->where('requirement_id', $requirement);
        }

        if ($project == 'all') {
            $planList = $query->where([
                    ['name', 'like', '%'.$name.'%'],
                    ['status', 'in', $status],
                    ['pid', '=', 0]
                ])
                ->order('id', 'desc')
                ->paginate([
                    'list_rows' => $limit,
                    'var_page' => 'page',
                    'page' => $page,
                    'query' => [
                        'name' => $name,
                        'status' => $status
                    ]
                ]);
        } else {
            $planList = $query->where([
                    ['name', 'like', '%'.$name.'%'],
                    ['project_id', '=', $project],
                    ['status', 'in', $status],
                    ['pid', '=', 0]
                ])
                ->order('id', 'desc')
                ->paginate([
                    'list_rows' => $limit,
                    'var_page' => 'page',
                    'page' => $page,
                    'query' => [
                        'name' => $name,
                        'project_id' => $project,
                        'status' => $status
                    ]
                ]);
        }

        $planListData = $planList->toArray()['data'];
        foreach ($planListData as &$plan) {
            $plan['project'] = $plan['project']['name'];
            $plan['start_time'] = date('Y-m-d H:i:s', $plan['start_time']);
            $plan['end_time'] = date('Y-m-d H:i:s', $plan['end_time']);
        }

        $data = [
            'code' => 0,
            'msg' => '',
            'count' => $planList->total(),
            'data' => $planListData
        ];

        return json($data);
    }

    // 任务添加页
    public function add()
    {
        // 找出当前用户所属的所有项目
        $userInfo = session('userInfo');
        $projectIds = UserProject::field('id,project_id')
            ->where('user_id', $userInfo['id'])
            ->column('project_id');
        $projects = \app\frontend\model\Project::field('id,name')->select($projectIds)->toArray();

        return view('', [
            'projects' => $projects
        ]);
    }

    // 任务添加页面保存接口
    public function save()
    {
        $params['name'] = trim(input('post.name', '', 'strip_tags'));
        $params['project_id'] = trim(input('post.project', '', 'strip_tags'));
        $params['desc'] = trim(input('post.desc', '', 'strip_tags'));
        $params['startTime'] = strtotime(trim(input('post.startTime', '', 'strip_tags')));
        $params['endTime'] = strtotime(trim(input('post.endTime', '', 'strip_tags')));
        $params['estimateTime'] = trim(input('post.estimateTime', '', 'strip_tags'));
        $params['priority'] = trim(input('post.priority', '', 'strip_tags'));

        $validate = Validate::rule([
            'name|名称' => 'require|max:20',
            'startTime|开始时间' => 'require',
            'endTime|结束时间' => 'require',
            'desc|详情描述' => 'max:255',
            'estimateTime|估算时间' => 'require|max:20',
            'priority|优先级' => 'require'
        ]);
        if (!$validate->check($params)) {
            return json([
                'code' => 1,
                'msg' => $validate->getError()
            ]);
        }

        // 启动事务
        Db::startTrans();
        try {
            $userInfo = session('userInfo');
            \app\frontend\model\Plan::create([
                'name' => $params['name'],
                'project_id' => $params['project_id'],
                'desc' => $params['desc'],
                'status' => 1,
                'start_time' => $params['startTime'],
                'end_time' => $params['endTime'],
                'user_id' => $userInfo['id'],
                'estimate_time' => $params['estimateTime'],
                'priority' => $params['priority']
            ]);

            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return json([
                'code' => 2,
                'msg' => $e->getMessage()
            ]);
        }

        return json([
            'code' => 0,
            'msg' => '保存成功'
        ]);
    }

    // 计划查看编辑页
    public function edit()
    {
        // 任务信息
        $id = (int)input('get.id', '', 'strip_tags');
        $plan = \app\frontend\model\Plan::field('id,name,desc,project_id,start_time,end_time,status,finish_time,estimate_time,priority')
            ->find($id)->toArray();
        $project = \app\frontend\model\Project::field('id,name')->find($plan['project_id'])->toArray();
        $plan['project'] = $project['name'];

        return view('', [
            'plan' => $plan
        ]);
    }

    // 编辑页面保存接口
    public function update()
    {
        // 计划信息
        $params['id'] = (int)trim(input('post.id', '', 'strip_tags'));
        $params['name'] =  trim(input('post.name', '', 'strip_tags'));
        $params['desc'] = trim(input('post.desc', '', 'strip_tags'));
        $params['startTime'] = strtotime(trim(input('post.startTime', '', 'strip_tags')));
        $params['endTime'] = strtotime(trim(input('post.endTime', '', 'strip_tags')));
        $params['estimateTime'] = trim(input('post.estimateTime', '', 'strip_tags'));
        $params['priority'] = trim(input('post.priority', '', 'strip_tags'));

        // 格式验证
        $validate = Validate::rule([
            'id|id' => 'require|integer',
            'name|名称' => 'require|max:20',
            'startTime|开始时间' => 'require',
            'endTime|结束时间' => 'require',
            'desc|详情描述' => 'max:255',
            'estimateTime|估算时间' => 'require|max:20',
            'priority|优先级' => 'require'
        ]);
        if (!$validate->check($params)) {
            return json([
                'code' => 1,
                'msg' => $validate->getError()
            ]);
        }

        // 优先级参数设置
        switch ($params['priority']) {
            case '低':
                $params['priority'] = 1;
                break;
            case '中':
                $params['priority'] = 2;
                break;
            case '高':
                $params['priority'] = 3;
                break;
            default:
                return json([
                    'code' => 2,
                    'msg' => '优先级参数错误'
                ]);
        }

        \app\frontend\model\Plan::update([
            'id' => $params['id'],
            'name' => $params['name'],
            'desc' => $params['desc'],
            'start_time' => $params['startTime'],
            'end_time' => $params['endTime'],
            'estimate_time' => $params['estimateTime'],
            'priority' => $params['priority']
        ]);

        return json([
            'code' => 0,
            'msg' => '修改成功'
        ]);
    }

    // 计划列表删除接口
    public function delete()
    {
        $id = (int)trim(input('post.id', '', 'strip_tags'));

        // 要先删除所有子计划才能删除该计划
        $subPlan = \app\frontend\model\Plan::where('pid', $id)->find();
        if (!empty($subPlan)) {
            return json([
                'code' => 1,
                'msg' => '要先删除所有子计划才能删除该计划'
            ]);
        }

        // 删除该计划生成的任务下的所有子任务才能删除该计划
        $task = \app\frontend\model\Task::where('plan_id', $id)->find();
        if (!empty($task)) {
            $subTask = \app\frontend\model\Task::where('pid', $task->id)->find();
            if (!empty($subTask)) {
                return json([
                    'code' => 2,
                    'msg' => '删除该计划生成的任务下的所有子任务才能删除该计划'
                ]);
            }
        }

        // 启动事务
        Db::startTrans();
        try {
            if (!empty($task)) {
                $task->delete();
            }
            \app\frontend\model\Plan::destroy($id);

            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return json([
                'code' => 2,
                'msg' => $e->getMessage()
            ]);
        }

        return json([
            'code' => 0,
            'msg' => '删除成功'
        ]);
    }

    // 任务列表多选删除接口
    public function deleteMulti()
    {
        $ids = input('post.ids', '', 'strip_tags');

        // 要先删除所有子计划才能删除计划
        $subPlans = \app\frontend\model\Plan::where('pid', 'in', $ids)->select();
        if (!$subPlans->isEmpty()) {
            return json([
                'code' => 1,
                'msg' => '要先删除所有子计划才能删除该计划'
            ]);
        }

        // 删除计划生成的任务下的所有子任务才能删除计划
        $taskIds = \app\frontend\model\Task::where('plan_id', 'in', $ids)->column('id');
        $subTask = \app\frontend\model\Task::where('pid', 'in', $taskIds)->find();
        if (!empty($subTask)) {
            return json([
                'code' => 2,
                'msg' => '删除计划生成的任务下的所有子任务才能删除计划'
            ]);
        }

        // 启动事务
        Db::startTrans();
        try {
            \app\frontend\model\Plan::destroy($ids);
            \app\frontend\model\Task::destroy(function ($query) use ($ids) {
                $query->where('plan_id', 'in', $ids);
            });

            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return json([
                'code' => 3,
                'msg' => $e->getMessage()
            ]);
        }

        return json([
            'code' => 0,
            'msg' => '删除成功'
        ]);
    }

    // 计划生成任务
    public function generate()
    {
        $id = (int)trim(input('post.id', '', 'strip_tags'));

        // 启动事务
        Db::startTrans();
        try {
            $planModel = \app\frontend\model\Plan::find($id);
            $planModel->status = 2;
            $planModel->save();

            \app\frontend\model\Task::create([
                'project_id' => $planModel->project_id,
                'name' => $planModel->name,
                'desc' => '',
                'user_id' => $planModel->user_id,
                'plan_id' => $id
            ]);

            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return json([
                'code' => 1,
                'msg' => $e->getMessage()
            ]);
        }

        return json([
            'code' => 0,
            'msg' => '生成成功'
        ]);
    }

    // 生成的任务页面
    public function task()
    {
        $id = (int)trim(input('get.id', '', 'strip_tags'));

        return view('', [
            'planId' => $id
        ]);
    }
}
